
'''
面向对象技术简介
    类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
    类变量：类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
    数据成员：类变量或者实例变量用于处理类及其实例对象的相关的数据。
    方法重写：如果从父类继承的方法不能满足子类的需求，可以对其进行改写，这个过程叫方法的覆盖（override），也称为方法的重写。
    实例变量：定义在方法中的变量，只作用于当前实例的类。
    继承：即一个派生类（derived class）继承基类（base class）的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
    实例化：创建一个类的实例，类的具体对象。
    方法：类中定义的函数。
    对象：通过类定义的数据结构实例。对象包括两个数据成员（类变量和实例变量）和方法。
'''
# 类对象支持两种操作：属性引用和实例化。
# 属性引用使用和 Python 中所有的属性引用一样的标准语法：obj.name。
class CustomClass:
    value = 12345
    def func(self):
        return 'CustomClass!'
cc = CustomClass()
print(cc.value, cc.func())
print()

# __init__() 特殊方法（构造方法）, 类的实例化操作会自动调用.
# __init__() 方法可以有参数，参数通过 __init__() 传递到类的实例化操作上.
class ComplexClass:
    def __init__(self, realpart, imagpart):
        self.real = realpart
        self.imag = imagpart
cc = ComplexClass(3.0, -4.5)
print(cc.real, cc.imag)
print()

# 类的方法与普通函数只有一个区别, 必须有一个额外的第一个参数名称, 按照惯例为 self, 也可为其他。
# self 代表的是类的实例，代表当前对象的地址，而 self.__class__ 则指向类。
class MyClass:
    def printSelf(self):
        print(self)
        print(self.__class__)
# MyClass().printSelf()
mc = MyClass()
mc.printSelf()
print()

class MyClass:
    def printSelf(haydn):
        print(haydn)
        print(haydn.__class__)
# MyClass().printSelf()
mc = MyClass()
mc.printSelf()
print()

# 继承 class DerivedClassName(BaseClassName1):
# 若是基类中有相同的方法名，而在子类使用时未指定，从左到右查找基类中是否包含该方法。
class People:
    # 基本属性
    name = ''
    age = 0
    # __private_attrs：两个下划线开头，声明该属性为私有属性，不能在类地外部被使用或直接访问，不能被继承。
    __weight = 0
    # __private_method：两个下划线开头，声明该方法为私有方法，只能在类的内部调用。
    # 构造方法
    def __init__(self, name, age, weight):
        self.name = name
        self.age = age
        self.__weight = weight
    def introduce(self):
        print("My name is %s. I'm %d years old. My weight is %d." % (self.name, self.age, self.__weight))
# 单继承
class Student(People):
    grade = 0
    def __init__(self, name, age, weight, grade):
        People.__init__(self, name, age, weight)
        self.grade = grade
    def introduce(self):
        print("My name is %s. I'm %d years old. I'm in grade %d." % (self.name, self.age, self.grade))
Student('Haydn', 10, 60, 3).introduce()
print()

'''
类专有方法
    __init__ : 构造函数，在生成对象时调用
    __del__ : 析构函数，释放对象时使用
    __repr__ : 打印，转换，用于显示给开发人员
    __str__: 用于显示给用户
    __setitem__ : 按照索引赋值
    __getitem__: 按照索引获取值
    __len__: 获得长度
    __cmp__: 比较运算
    __call__: 函数调用
    __add__: 加运算
    __sub__: 减运算
    __mul__: 乘运算
    __div__: 除运算
    __mod__: 求余运算
    __pow__: 乘方
'''

# 运算符重载
class Vector2D:
    def __init__(self, a, b):
        self.a = a
        self.b = b
    def __str__(self):
        return 'Vector2D(%d, %d)' % (self.a, self.b)
    def __add__(self, other):
        return Vector2D(self.a + other.a, self.b + other.b)
v1 = Vector2D(5, 5)
v2 = Vector2D(-1, 4)
print(v1, v2)
print("v1+v2:", v1+v2)
print()
